/**************************************************************************/ /**
 * @file     load_mv.h
 * @brief    播放 video / music 文件
 * @version  V3.2
 * @date     2022.03.11
 ******************************************************************************/
#ifndef __LOAD_MV_H__
#define __LOAD_MV_H__

//------------------------------------------------------头文件依赖-----------------------------------------------//
#include "main.h"

//------------------------------------------------------全局宏-----------------------------------------------//
// avi 视频播放用定时器
#define AVI_TIMR					BTIMR0
#define AVI_TIMR_HANDLER			BTIMR0_Handler


#define PCM_BUFSIZE 		(2048) //此处直接定义成2048，比较好的方法应该是根据 wav/avi 文件头解析出的大小在堆中申请空间 

#define VIDEO_LAYER			LCD_LAYER_2//播放视频使用图层2

/* WAV音频播放选项测试 */
#define MUSIC_SDRAM_ENABLE 		0 // 0 : (默认)音频数据存放至SPI-Flash内(*.wav文件形式)    1 : (待测试)音频数据存放至SDRAM内

//------------------------------------------------------类型声明-----------------------------------------------//

typedef enum 
{
	FREE = 0,
	BUSY
}mv_flag_t;

/* 音视频全局播放状态 */
typedef enum {
    fsm_rt_parser_err 	= -4,
    fsm_rt_read_err 	= -3,
    fsm_rt_open_err 	= -2,
    fsm_rt_err 			= -1,

    fsm_rt_waiting 		= 0, //空闲等待
    fsm_rt_start 		= 1, //启动解析
    fsm_rt_on_going 	= 2, //播放中ing
    fsm_rt_cpl 			= 3, //结束播放
} fsm_rt_t;

/* 音视频类型 */
typedef enum {
    VIDEO = 0,   //视频流(*.avi)
    MUSIC,       //音频流(*.wav)
} play_type_t;

typedef struct {
	char path[64];	  //文件绝对路径
    play_type_t type; //文件类型
	uint16_t post[2]; //视频播放区域的起始位置[xs, ys]
	uint16_t FrameCount; //当前插放帧计数
    volatile fsm_rt_t fsm_state; //当前播放状态
	
    volatile uint8_t frame_flag 	: 1; //avi 一帧结束标志  	0/空闲-帧结束      	1/忙碌-播放帧
	volatile uint8_t audio_flag 	: 1; //dac dma 传输完成标志	0/空闲      		1/忙碌
} play_mv_t;

//------------------------------------------------------全局变量-----------------------------------------------//
extern play_mv_t Play_Task_Handler; //播放任务句柄

extern volatile uint32_t Video_Finish_Time; //区域视频重复播放次数 : 0/第一次未播完    (N >= 1)/播完 N 次
extern uint32_t Video_Time_Max;             //区域视频重复播放最大次数(uint32_t有效范围)

extern uint8_t JPEG_Decoder_Buff[LV_HOR_RES_MAX * LV_VER_RES_MAX * sizeof(lv_color_t)]; //JPEG图片全局解码缓冲区

//------------------------------------------------------函数声明-----------------------------------------------//
/**
  \brief		播放任务轮询
  \param [in]	mv		 : 播放任务句柄
  \return       0 : 空闲	1 : 忙碌    -1:抛出错误
  \note    		需要在 while (bool) 中轮询
 */
int play_mv_task_handler(play_mv_t *mv_task);

/**
  \brief		初始化播放任务
  \param [in]	mv		 	: 播放任务句柄
				file_path 	: 文件路径 \\ The variable to which the pointer points must not be released until the function ends the called procedure
  \return       fsm_rt_t 	: 播放状态
  \note    		\
 */
fsm_rt_t play_mv_init(play_mv_t *mv, const char *file_path);

/**
  \brief		关闭播放任务
  \param [in]	mv	: 播放任务句柄
  \return       fsm_rt_t : 播放状态
  \note    		根据当前播放源类型以关闭相关外设
 */
fsm_rt_t close_mv(play_mv_t *mv);

/**
  \brief		暂停播放
  \param [in]	mv	: 播放任务句柄
  \return       /
  \note    		仅实现音频
 */
void pause_mv(play_mv_t *mv);

/**
  \brief		恢复播放
  \param [in]	mv	: 播放任务句柄
  \return       /
  \note    		仅实现音频
 */
void restore_mv(play_mv_t *mv);

//--------------------------------------- play_mv_init(mv) 会覆盖以下属性设置 ------------------------------------------//
/**
  \brief		改变视频播放位置
  \param [in]	lcd_layer	: 图层
				xs / ys		: 起始位置
  \return       /
  \note    		视频源大小一般不可改变, 可使新设置的播放区域大小自动适配源的大小( Avix )，请在 play_mv_init(mv) 之后调用
 */
void video_change_post(uint8_t lcd_layer, uint16_t xs, uint16_t ys);

/**
  \brief		改变视频图层透明度
  \param [in]	lcd_layer	: 图层
				alpha		: 透明度
  \return       /
  \note    		图层 x 的 constant alpha，用于 blending。
				Blending 公式：
				BC = (C * CONSTA + Cs * (255 - CONSTA))/255
				BC: blended color
				C : current layer color
				Cs: subjacent layers blended color
				有如下几种 blending 情况：
				图层 1 和图层 2 都使能时：先将图层 1 和背景颜色进行 blending，然后将图层 2 和
				blending 后的图层进行 blending。
				图层 1 或图层 2 仅有一个图层使能时：将被使能的图层和背景颜色进行 blending。
				两个图层都不使能时：仅显示背景色。
 */
void video_change_alpha(uint8_t lcd_layer, uint8_t alpha);

/**
  \brief		改变视频输出格式
  \param [in]	format	: 解码输出格式，可取值JPEG_OUT_YUV、JPEG_OUT_YUVsp、JPEG_OUT_XRGB888、...详见 swm341_jpeg.h
				dither	: RGB565 dithering enable
  \return       /
  \note    		仅 format 为 JPEG_OUT_RGB565 时，dither 有效，请在 play_mv_init(mv) 之后调用
 */
void video_change_format(uint8_t format, uint8_t dither);

#endif //__LOAD_MV_H__
